package monfox.stack.iec61850.mms.client.impl;

import java.util.Vector;

import monfox.log.Logger;
import monfox.stack.iec61850.api.GenDataNode;
import monfox.stack.iec61850.api.ModelCommunicationException;
import monfox.stack.iec61850.api.ModelException;
import monfox.stack.iec61850.api.ModelServiceException;
import monfox.stack.iec61850.api.ModelTimeoutException;
import monfox.stack.iec61850.api.ModelValueException;
import monfox.stack.iec61850.api.client.DataNode;
import monfox.stack.iec61850.api.client.InfoLog;
import monfox.stack.iec61850.api.client.ModelNode;
import monfox.stack.iec61850.mms.impl.MmsModelConverter;
import monfox.stack.osi.api.CommunicationsException;
import monfox.stack.osi.api.TimeoutException;
import monfox.stack.osi.api.ValueException;
import monfox.stack.osi.mms.DataTypeDesc;
import monfox.stack.osi.mms.MMS_GetVariableAccessAttributes_PendingRequest;
import monfox.stack.osi.mms.MMS_GetVariableAccessAttributes_Req;
import monfox.stack.osi.mms.MMS_GetVariableAccessAttributes_Rsp;
import monfox.stack.osi.mms.ObjectName;
import monfox.stack.osi.mms.TypeDesc;

public class ACSI_GetDataDefinition extends ACSI_Service {
    private String domain = null;

    private String object = null;
    private Listener c = null;
    private DataNode d;
    private InfoLog e = null;

    private MmsModelConverter f = new MmsModelConverter();

    private MMS_GetVariableAccessAttributes_PendingRequest g = null;
    private static Logger h = Logger.getInstance("DOSI", "IEC61850-SERVICES", "ACSI_GetDataDefinition");

    public ACSI_GetDataDefinition(MmsIEC61850Client paramMmsIEC61850Client, String paramString)
            throws ModelServiceException {
        super(paramMmsIEC61850Client, "GetDataDefinition");

        ObjectName paramMms = a(paramString);
        this.domain = paramMms.getDomainID();
        this.object = paramMms.getItemID();
    }

    public void setInfoLog(InfoLog paramInfoLog) {
        this.e = paramInfoLog;
    }

    public ACSI_GetDataDefinition(MmsIEC61850Client paramMmsIEC61850Client, DataNode paramDataNode)
            throws ModelServiceException {
        super(paramMmsIEC61850Client, "GetDataDefinition");

        this.domain = paramDataNode.getDeviceName();
        this.object = getClient().convert2mms(paramDataNode.getObjectRef());

        this.d = paramDataNode;
    }

    public String getLDeviceName() {
        return this.domain;
    }

    public String getElementName() {
        return this.object;
    }

    public Result getResult() throws ModelServiceException, ModelCommunicationException, ModelValueException {
        return (Result) d();
    }

    final void a() throws ModelCommunicationException, ModelValueException {
        try {
            MMS_GetVariableAccessAttributes_Req localMMS_GetVariableAccessAttributes_Req = new MMS_GetVariableAccessAttributes_Req(
                    ObjectName.Domain(this.domain, this.object));

            this.g = getValidMMS().send(localMMS_GetVariableAccessAttributes_Req, 3000/*
                                                                                     * getTimeoutMillis
																					 * (
																					 * )
																					 */);

            return;
        } catch (CommunicationsException localCommunicationsException) {
            throw new ModelCommunicationException("communications error on send", localCommunicationsException);
        } catch (ValueException localValueException) {
            throw new ModelValueException("value exception error on send", localValueException);
        }
    }

    final synchronized void b() throws ModelCommunicationException, ModelValueException, ModelTimeoutException {
        if (this.g == null)
            return;

        new Vector();
        try {
            Object typeDesc = null;
            try {
                MMS_GetVariableAccessAttributes_Rsp rsp = this.g.rsp();
                typeDesc = ((MMS_GetVariableAccessAttributes_Rsp) rsp).getTypeDescription();
                // if (rsp.isError()) {
                // typeDesc = new
                // ModelServiceException("error in getting definitions (" +
                // this.domain + "/" + this.object
                // + ")\n" + ((MMS_GetVariableAccessAttributes_Rsp)
                // rsp).getServiceError());
                //
                // a(b((ModelServiceException) typeDesc));
                // return;
                // }
                // if (((MMS_GetVariableAccessAttributes_Rsp) rsp).isReject()) {
                // typeDesc = new
                // ModelServiceException("reject in getting definitions (" +
                // this.domain + "/" + this.object
                // + ")\n" + ((MMS_GetVariableAccessAttributes_Rsp)
                // rsp).getReject());
                //
                // a(b((ModelServiceException) typeDesc));
                // return;
                // }
            } catch (Exception e) {
                e.printStackTrace();
            }

            Object localObject2;
            if (typeDesc == null) {

                // localObject2 = new
                // ModelServiceException("no type-def returned for (" +
                // this.domain + "/" + this.object + ")");
                //
                // a(b((ModelServiceException) localObject2));
                // return;
                typeDesc = new DataTypeDesc(getMMSAPI());
            }

            if ((localObject2 = this.d) == null) {
                localObject2 = (DataNode) getModelApi().newModelNode(this.object);
            }

            try {
                this.f.syncModelWithServer(this.e, getClient().getAssociationContext(), (GenDataNode) localObject2,
                        (TypeDesc) typeDesc);

                localObject2 = new Result((DataNode) localObject2);
                a((ACSI_Service.Result) localObject2);
            } catch (ModelException localModelException) {
                h.debug("exception in processing GetDefinitions for  " + typeDesc, localModelException);
                typeDesc = new ModelServiceException("data error in extracting data values", localModelException);
                a(b((ModelServiceException) typeDesc));

                return;
            }
        } catch (Exception localTimeoutException) {
            localTimeoutException.printStackTrace();
            // throw new ModelTimeoutException("timeout",
            // localTimeoutException);
        }
    }

    private Result b(ModelServiceException paramModelServiceException) {
        return new Result(paramModelServiceException);
    }

    final void c() {
        if (this.c == null)
            return;
        try {
            this.c.handleResult(this);

            return;
        } catch (Exception localException) {
            h.error("exception in listener invocation", localException);
        }
    }

    public void setListener(Listener paramListener) {
        this.c = paramListener;
    }

    public Listener getListener() {
        return this.c;
    }

    public ACSI_GetDataDefinition send() throws ModelServiceException, ModelCommunicationException, ModelValueException {
        return (ACSI_GetDataDefinition) e();
    }

    public class Result extends ACSI_Service.Result {
        private DataNode a = null;

        Result(ModelServiceException arg2) {
            super(arg2);
        }

        Result(DataNode arg2) {
            super();
            Object localObject;
            this.a = arg2;
        }

        public DataNode getDataNode() {
            return this.a;
        }

        public String toString() {
            StringBuffer localStringBuffer = new StringBuffer();
            toString(localStringBuffer);
            return localStringBuffer.toString();
        }

        public void toString(StringBuffer paramStringBuffer) {
            paramStringBuffer.append("\n--[ GetDataDefinition.Result ]---------------------------");
            paramStringBuffer.append("\n");
            if (this.a != null) {
                paramStringBuffer.append("\n   dataNode: ");
                paramStringBuffer.append("\n");
                this.a.toString(paramStringBuffer, 2, ModelNode.DEFAULT_FORMAT);
            }

            if (getException() != null) {
                paramStringBuffer.append("\n   exception:");
                paramStringBuffer.append("\n");
                paramStringBuffer.append(getException().getMessage());
            }

            paramStringBuffer.append("\n");
            paramStringBuffer.append("\n--[ GetDataDefinition.Result ]---------------------------");
        }
    }

    public static abstract interface Listener {
        public abstract void handleResult(ACSI_GetDataDefinition paramACSI_GetDataDefinition);
    }

    @Override
    monfox.stack.iec61850.mms.client.impl.ACSI_Service.Result a(ModelServiceException paramModelServiceException) {
        // TODO Auto-generated method stub
        return null;
    }
}